package com.qili.controller;

import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qili.entity.supervisor.SupervisorFile;
import com.qili.entity.supervisor.SupervisorFileTemp;
import com.qili.mapper.it.ItDicMapper;
import com.qili.mapper.it.ItFileMapper;
import com.qili.service.it.ItIndexService;
import com.qili.service.supervisor.SupervisorFileService;
import com.qili.service.supervisor.SupervisorFileTempService;
import com.qili.util.*;
import net.sf.jxls.transformer.XLSTransformer;
import org.apache.commons.io.FileUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.*;

/**
 * @author zhangxiaopeng
 * @date 2021-05-24
 */
@Controller
@RequestMapping("/search/statistics")
public class StatisticsITController {

    @Autowired
    ItFileMapper itFileMapper;
    @Autowired
    ItDicMapper itDicMapper;
    @Autowired
    ItIndexService itIndexService;
    @Autowired
    UploadUtil uploadUtil;
    @Autowired
    SupervisorFileTempService tempService;
    @Autowired
    SupervisorFileService supervisorFileService;

    /** 线程池（当前线程池大小为12） */
    private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(12, 20, 30, TimeUnit.MINUTES, new LinkedBlockingDeque<>());

    /**
     * 跳转知识库统计
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "it")
    @RequiresPermissions("zn:jc:zsk")
    public String statisticsIT(Model model) {
        return "/decision/ItFormInfo/statisticsIT";
    }

    /**
     * 树形下拉和it知识库查询一样
     *
     * 2022年5月16日14:00:01 【修改】 数据库增加一个 path_key 存放的是当前节点的id路径可以直接查询出来
     *
     * @return
     */
    @RequestMapping("selectIT")
    @ResponseBody
    public JsonUtil selectIT(Model model, HttpServletRequest request) throws InterruptedException {
        // JsonUtil fileByrecursive = this.getFileByrecursive(); 递归方法
        JsonUtil result = new JsonUtil();
        PageHelper.startPage(1, 100000);
        List<Map<String, Object>> listMap = new ArrayList<>();

        // 查询第二级,根结点不查
        List<SupervisorFile> supers = itDicMapper.getFirst(new HashMap()); // 父级
        for (SupervisorFile menu : supers) {
            Map<String, Object> map = new HashMap<>();
            map.put("id",menu.getId());
            // 查询当前目录下所有文件,取出path_key直接查询 是按照逗号分隔的
            int num = itFileMapper.getZskfileType2Or1(menu.getId(),"2");
            map.put("label",menu.getFileName() + "(" + num + ")");
            // 判断是否存在子节点
            Integer flag = itFileMapper.isChilds(menu.getId(),"1");
            map.put("isLeaf",true);
            if (flag != null){
                map.put("isLeaf",false);
            }
            listMap.add(map);
        }
        result.setData(listMap);
        return result;
    }

    /**
     * 根据父id查询孩子节点
     * @param parentId
     * @return
     */
    @RequestMapping("/selectChildsByParentId")
    @ResponseBody
    public JsonUtil selectChildsByParentId(String parentId){
        JsonUtil result = new JsonUtil();
        PageHelper.startPage(1, 100000);
        List<Map<String, Object>> listMap = new ArrayList<>();
        // 根据父级id查询子节点
        List<SupervisorFile> childs = itFileMapper.selectChildsByParentId(parentId);
        // 获取到当前父id的所有儿子节点的id
        String ids = itFileMapper.selectIdPj(parentId,"1");
        // 查询文件数量
        List<Map<String,String>> numList = itFileMapper.getNumByIds(ids);
        // 查询数量
        List<Map<String,String>> isChildsList = itFileMapper.isChildsFlag(ids);
        if (!CollectionUtils.isEmpty(childs)){
            int num = 0;
            for (SupervisorFile child : childs) {
                Map<String, Object> map = new HashMap<>();
                map.put("id",child.getId());
                map.put("label",child.getFileName() + "(0"+")");
                for (Map<String, String> numMap : numList) {
                    if (numMap.containsKey("tempName") && numMap.get("tempName").equals(child.getId())){
                        // 对应的数据
                        String num1 = String.valueOf(numMap.get("num"));
                        map.put("label",child.getFileName() + "(" + num1 + ")");
                        break;
                    }
                }
                // 是否子节点
                for (Map<String, String> isChildsMap : isChildsList) {
                    if (isChildsMap.get("id").equals(child.getId())){
                        boolean flag = Boolean.parseBoolean(isChildsMap.get("flag"));
                        map.put("isLeaf",flag);
                        break;
                    }
                }
//                Integer flag = itFileMapper.isChilds(child.getId(),"1");
//                map.put("isLeaf",true);
//                if (flag != null){
//                    map.put("isLeaf",false);
//                }
                listMap.add(map);
            }
        }
        result.setData(listMap);
        return result;
    }

    /**
     * 2022年5月16日14:00:55 【修改】
     * 之前写的查询 使用递归,数量大，效率慢
     * @return
     * @throws InterruptedException
     */
    private JsonUtil getFileByrecursive() throws InterruptedException {
        JsonUtil re = new JsonUtil();
        PageHelper.startPage(1, 100000);
        Map paraMap = new HashMap();
        // 文件夹
        SupervisorFile file = new SupervisorFile();
        file.setZskfileType("1");
        List<SupervisorFile> sysMenus = itFileMapper.selectFile(file); // 文件夹
        // 文件
        SupervisorFile filell = new SupervisorFile();
        List<SupervisorFile> sysMenusfile = itFileMapper.selectFile(filell); // 所有文件
        List<SupervisorFile> supers = itDicMapper.getFirst(paraMap); // 父级
        int pNum = 1000;
        JSONArray jsonArr = new JSONArray();
        List<Map> listMap = new ArrayList<>();
        // 初始化计时器
        CountDownLatch cdl = new CountDownLatch(supers.size());
        System.out.println("====== 线程开始 =====");

        for (SupervisorFile menu : supers) {
            // 开启线程
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    Map map1 = new HashMap();
                    map1.put("children", getChilds(menu, sysMenus, sysMenusfile));
                    map1.put("id", menu.getId());
                    Map<String, Integer> mapnum = new HashMap<>();
                    mapnum.put("num", 0);
                    getChildsFile(menu, mapnum, sysMenusfile);
                    Integer num1 = mapnum.get("num");
                    map1.put("label", menu.getFileName() + "(" + num1 + ")");
                    // 添加 创建时间 排序
                    map1.put("createTime",menu.getCreateDate());
                    listMap.add(map1);
//                    Thread t = Thread.currentThread();
//                    String name = t.getName();
//                    System.out.println(name+"：执行到 "+menu.getFileName());
                    // 闭锁-1
                    cdl.countDown();
                }
            });
        }
        // 调用闭锁的await()方法，该线程会被挂起，它会等待直到count值为0才继续执行
        // 这样我们就能确保上面多线程都执行完了才走后续代码
        cdl.await();
        //关闭线程池
//        executor.shutdown();
        System.out.println("====== 线程结束 =====");
        // 对多线程处理的数据进行排序
        listMap.sort(new Comparator<Map>() {
            @Override
            public int compare(Map o1, Map o2) {
                try {
                    if (((Date) o1.get("createTime")).after((Date) o2.get("createTime"))) {
                        return -1;
                    } else {
                        return 1;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return 0;
            }
        });
        re.setData(listMap);
        return re;
    }

    /**
     * 获取子节点
     * @param menu 当前菜单
     * @param menuList  文件夹
     * @param sysMenusfile 所有文件
     * @return
     */
    public List<Map> getChilds(SupervisorFile menu, List<SupervisorFile> menuList, List<SupervisorFile> sysMenusfile) {
        List<Map> mapsList = new ArrayList<>();
        for (SupervisorFile menus : menuList) {
            if (menu.getId().equals(menus.getSuperiorId())) {
                Map map = new HashMap();
                map.put("id", menus.getId());
                // 获取文件的数量
                List<Map> m = getChilds(menus,  menuList, sysMenusfile);
                Map<String, Integer> mapnum = new HashMap<>();
                mapnum.put("num", 0);
                getChildsFile(menus, mapnum, sysMenusfile);
                Integer num1 = mapnum.get("num");
                map.put("label", menus.getFileName() + "(" + num1 + ")");
                if (m != null && m.size() > 0) {
                    map.put("children", m);
                }
                if (map != null && map.size() > 0) {
                    mapsList.add(map);
                }
            }
        }
        return mapsList;
    }

    /**
     * @param menu
     * @param menuList
     * @param sysMenusfile
     * @param listExprot
     * @Author:zhaoyongke
     * @Description:  导出
     * @Date:13:39 2021/5/28
     */
    public void getChildsExprot(SupervisorFile menu, List<SupervisorFile> menuList, List<SupervisorFile> sysMenusfile, ArrayList listExprot) {
        for (SupervisorFile menus : menuList) {
            if (menu.getId().equals(menus.getSuperiorId())) {
                Map map = new HashMap();
                Map<String, Integer> mapnum = new HashMap<>();
                mapnum.put("num", 0);
                getChildsFile(menus, mapnum, sysMenusfile);
                Integer num1 = mapnum.get("num");
                // 处理空格
                StringBuffer space = new StringBuffer();
                if (menus.getUrl().indexOf("/www/server/jar/cc/") > -1) {
                    String replacenew = menus.getUrl().replace("/www/server/jar/cc/", "");
                    String[] split = replacenew.split("/");
                    for (int j = 0; j < split.length; j++) {
                        space.append("     ");//这里是空格
                    }
                    map.put("fileName", space.toString() + menus.getFileName() );
                    map.put("num",num1);
                    if (map != null && map.size() > 0) {
                        listExprot.add(map);
                    }
                    map.put("pageView", listExprot.size());
                    getChildsExprot(menus, menuList, sysMenusfile, listExprot);

                }
            }
        }


    }

    /**
     *
     * @param menu 当前父级
     * @param map 空的数据集合
     * @param sysMenusfile 所有文件
     */
    public void getChildsFile(SupervisorFile menu, Map<String, Integer> map, List<SupervisorFile> sysMenusfile) {
        for (SupervisorFile menus : sysMenusfile) {
            if (menu.getId().equals(menus.getSuperiorId())) {
                if ("2".equals(menus.getZskfileType())) {
                    int ss = map.get("num") + 1;
                    map.put("num", ss);
                }
                // 获取文件的数量
                getChildsFile(menus, map, sysMenusfile);

            }
        }
    }


    public List<Map> selectStatiIT(ArrayList<SupervisorFile> childs) {
        List<Map> mapsList = new ArrayList<>();
        if (childs != null && childs.size() > 0) {
            for (SupervisorFile it : childs) {
                Map map = new HashMap();
                map.put("id", it.getId());
                map.put("label", it.getFileName());
                List<Map> maps = selectStatiIT(it.getChilds());
                if (maps != null && maps.size() > 0) {
                    map.put("children", maps);
                }
                if (map != null && map.size() > 0) {
                    mapsList.add(map);
                }
            }
        }
        return mapsList;
    }


    /**
     * 对应文件的列表
     *
     * @param id
     * @param page
     * @param limit
     * @return
     */
    @RequestMapping("selectitXq")
    @ResponseBody
    public ReType selectitXq(String id, int page, int limit) {
        Map map = new HashMap();
        map.put("id", id);
        map.put("type", "2");
        List<SupervisorFile> list = new ArrayList<>();
        Page<SupervisorFile> tPage = PageHelper.startPage(page, limit);
        if (StringUtil.isNotBlank(id)) {
            map.put("id", id);
            list = itFileMapper.selectStatisticsIT(map);
        }
        return new ReType(tPage.getTotal(), list);
    }


    /**
     * 树形下拉根据id查询
     *
     * @param id
     * @return
     */
    @RequestMapping("selectXl")
    @ResponseBody
    public List<SupervisorFile> selectXl(String id) {
        Map map = new HashMap();
        map.put("id", id);
        List<SupervisorFile> list = itFileMapper.selectStatisticsIT(map);
        return list;
    }

    /**
     * 知识库统计导出excel
     *
     * @param request
     * @param response
     */
    @RequestMapping("exportTable")
    public void exportTable(HttpServletRequest request, HttpServletResponse response,String id) {
        String fileName = "知识库统计表_" + DateUtil.getCurrentDateNoSpliter();
//        ArrayList exprotList = getExprotList(); // 知识库统计导出所有的
        // 2022年5月24日11:21:19 修改查询方式为 层级导出，根据id查询表当前目录和子级
        ArrayList list = getExprotListById(id);
        HashMap map1 = new HashMap();
        map1.put("lists", list);
        map1.put("name", "知识库统计");
        try {
            ExcelExportUtil.exportExcel(response, map1, fileName, "87001");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private ArrayList getExprotListById(String parentId) {
        PageHelper.startPage(1, 100000);
        // 查询父级
        SupervisorFile supervisorFile = itFileMapper.selectByPrimaryKey(parentId);
        // 根据父级id查询子节点
        List<SupervisorFile> childs = itFileMapper.selectChildsByParentId(parentId);
        // 获取到当前父id的所有儿子节点的id
        String ids = itFileMapper.selectIdPj(parentId,"1");
        // 查询文件数量
        List<Map<String,String>> numList = itFileMapper.getNumByIds(ids);
        // 创建返回集
        ArrayList listExprot = new ArrayList();
        if (!CollectionUtils.isEmpty(childs)){
            // 第一级添加进行
            Map<String, Object> oneMap = new HashMap<>();
            oneMap.put("pageView",1);
            oneMap.put("fileName",supervisorFile.getFileName());
            List<Map<String, String>> parentNum = itFileMapper.getNumByIds(parentId);
            oneMap.put("num",String.valueOf(parentNum.get(0).get("num")));
            listExprot.add(oneMap);
            for (int i = 0; i < childs.size(); i++) {
                SupervisorFile child = childs.get(i);
                // 需要导出的数据
                Map<String, Object> map = new HashMap<>();
                // 序号
                map.put("pageView",(i+2));
                // 判断当前结点是否存在子节点
                map.put("fileName","    " + child.getFileName());
                map.put("num","0");
                for (Map<String, String> numMap : numList) {
                    if (numMap.containsKey("tempName") && numMap.get("tempName").equals(child.getId())){
                        // 对应的数据
                        String num1 = String.valueOf(numMap.get("num"));
                        map.put("num",num1);
                        break;
                    }
                }
                listExprot.add(map);
        }
        }
        return listExprot;
    }

    /**
    * @Author:zhaoyongke
    * @Description: 获取导出的数据
    * @Date:13:54 2021/5/28
    */
    public  ArrayList  getExprotList(){

        PageHelper.startPage(1, 100000);
        Map paraMap = new HashMap();
        // 只获取文件夹
        SupervisorFile file = new SupervisorFile();
        file.setZskfileType("1");
        List<SupervisorFile> sysMenus = itFileMapper.selectFile(file);
        // 所有文件
        SupervisorFile filell = new SupervisorFile();
        List<SupervisorFile> sysMenusfile = itFileMapper.selectFile(filell);
        // 一级文件夹
        List<SupervisorFile> supers = itDicMapper.getFirst(paraMap);
        ArrayList listExprot = new ArrayList();
        for (SupervisorFile menu : supers) {
            Map mapexport = new HashMap();
            //文件数量
            //--------(1)start 处理文件本级文件名称（数量）------
            Map<String, Integer> mapnum = new HashMap<>();
            mapnum.put("num", 0);
            mapnum.put("kgnum", 0);
            getChildsFile(menu, mapnum, sysMenusfile);
            Integer num1 = mapnum.get("num");
            //--------end------
            //-------(2)------------
            mapexport.put("fileName", menu.getFileName());
            mapexport.put("num",num1);
            // 添加父级节点
            listExprot.add(mapexport);
            mapexport.put("pageView", listExprot.size());
            // 添加子节点 以及追加空格
            getChildsExprot(menu, sysMenus, sysMenusfile, listExprot);
        }
        return listExprot;
    }

    /**
     * 知识库统计预览excel
     *
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping("viewTable")
    public JsonUtil viewTable(HttpServletRequest request, HttpServletResponse response, String id) {
        JsonUtil result = new JsonUtil();
        try {
            String fileName = "知识库统计表_" + DateUtil.getCurrentDateNoSpliter();
//            ArrayList exprotList = getExprotList(); 同导出一样
            ArrayList list = getExprotListById(id);
            HashMap map1 = new HashMap();
            map1.put("lists", list);
            map1.put("name", "知识库统计");
            File formExcel = createFormExcel("87001", fileName, map1);
            String tempFilePath = uploadUtil.getTempPath() + File.separator + new Date().getTime()
                    + File.separator + fileName + formExcel.getName().substring(formExcel.getName().lastIndexOf("."));
            File tempFile = new File(tempFilePath);
            if (!tempFile.getParentFile().exists()) {
                tempFile.getParentFile().mkdirs();
            }
            tempFile.createNewFile();
            FileUtils.copyFile(formExcel, tempFile);
            formExcel.delete();
            SupervisorFileTemp temp = new SupervisorFileTemp();
            temp.setUrl(tempFile.getPath());
            temp.setFileName(tempFile.getName());
            temp.setFileType(tempFile.getName().substring(tempFile.getName().lastIndexOf(".")));
            temp.setType("tz");
            tempService.insertSelective(temp);
            result.setFlag(true);
            result.setData(temp.getId());
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 创建表单临时表格文件
     *
     * @param fileName
     * @param dataMap
     * @return
     */
    public File createFormExcel(String ptid, String fileName, HashMap dataMap) {
        try {
            // 获取模板信息
            String srcFilePath = FilePathUtil.getPathConfigTemplateFile(ptid);
            //生成的临时导出文件
            File destFile = File.createTempFile(fileName, ".xls");
            //  开始转换。利用  transformer 转到Excel
            XLSTransformer transformer = new XLSTransformer();
            // 参数：srcFilePath：模板源文件    cMap：需要导出的数据   destFile.getAbsolutePath()：下载的目标文件
            transformer.transformXLS(srcFilePath, dataMap, destFile.getAbsolutePath());
            return destFile;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InvalidFormatException e) {
            e.printStackTrace();
        }
        return null;
    }

}
